#include<iostream>
#include<fstream>
#include<cmath>
#include<vector>
#include "../programming1/EquationSolver.h"
#include "BSpline_LinearSpline.h"
#include "BSpline_CubicSpline.h"
#include "BSpline_QuadraticSpline.h"
using namespace std;

class Func : public Function {
    public:
        virtual double operator () (const double& x)  {
            return 1 / (1 + x*x);
        }
         virtual double diff (const double& x)  {
            return -2*x / (1 + x*x) / (1 + x*x);
         }
        virtual double diff2 (const double& x) {
            return (-2 + 6*x*x) / (1 + x*x) / (1 + x*x) / (1 + x*x);
        }
} func;

int main(){

	LinearBSpline  linearBspline= LinearBSplineInterpolation( func, -5, 10);
	CubicBSpline  natural_cubicBspline= CubicBSplineInterpolation ( func, -5, 10, "natural");
	CubicBSpline complete_cubicBspline = CubicBSplineInterpolation ( func, -5, 10, "complete");
	CubicBSpline ssd_cubicBspline = CubicBSplineInterpolation ( func, -5, 10, "ssd");
	QuadraticBSpline quadraticBspline = QuadraticBSplineInterpolation ( func, -5, 10);
	
	ofstream outd("d.csv");
	vector<double> a = {-3.5,-3,-0.5,0,0.5,3,3.5};
	outd << "a_i,ESL,ES1,ES2,ES3,ESQ" << endl;
	for(int i = 0; i < 7; ++ i) {
		outd << a[i] << ',' << fabs(linearBspline.getValue(a[i]) - func(a[i])) << ',' << fabs(natural_cubicBspline.getValue(a[i]) - func(a[i])) << ',' << fabs(complete_cubicBspline.getValue(a[i]) - func(a[i])) << ',' << fabs(ssd_cubicBspline.getValue(a[i]) - func(a[i])) << ',' << fabs(quadraticBspline.getValue(a[i]) - func(a[i])) << endl;
	}
}
